/* 与大多数全局对象不同Reflect并非一个构造函数，
所以不能通过new运算符对其进行调用，或者将Reflect对象作为一个函数来调用。
Reflect的所有属性和方法都是静态的（就像Math对象）

Proxy 对象用于创建一个对象的代理，从而实现基本操作的拦截和自定义（如属性查找、赋值、枚举、函数调用等）
receiver 当你使用 Proxy 来代理一个对象时，你可以选择将返回的值赋值给一个新的变量，
这个新的变量就是 receiver。简单来说，当你从一个代理对象中读取一个属性时，
你通常会将返回的值赋给一个新的变量。这个新的变量就是 receiver。
在 get 陷阱中，你可以使用这个 receiver 参数来决定返回的值应该赋值给哪个变量。
如果你不关心这个值应该赋值给哪个变量，你可以忽略这个参数。
*/
type Person = {
  name: string,
  age: number,
  text: string
}


const proxy = (object: any, key: any) => {
  return new Proxy(object, {
      get(target, prop, receiver) {
          console.log(`get key======>${key}`);
          return Reflect.get(target, prop, receiver)
      },

      set(target, prop, value, receiver) {
          console.log(`set key======>${key}`);

          return Reflect.set(target, prop, value, receiver)
      }
  })
}

// keyof 遍历对象的键
/* 这是一个解构赋值的形式，其中T是一个类型，而keyof T是一个联合类型，它包含了T中所有的属性键。
这种形式通常用于遍历对象的所有属性。 */
const logAccess = <T>(object: T, key: keyof T): T => {
  return proxy(object, key)
}

let man: Person = logAccess({
  name: "小满",
  age: 20,
  text: "我的很小"
}, 'age')


let man2 = logAccess({
  id:1,
  name:"小满2"
}, 'name')

man.age = 30

console.log(man);
